package com.zb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.WorkConstant;
import com.zb.entity.*;
import com.zb.mapper.ZjWorkSuspendMapper;
import com.zb.mobile.NetworkMobileWorkSuspendVo;
import com.zb.service.*;
import com.zb.view.ViewNetworkEmpAccount;
import com.zb.vo.WorkLogVo;
import com.zb.vo.WorkSuspendChecklVo;
import com.zb.vo.WorkSuspendDetailVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 工单挂起表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2024-03-18
 */
@Service
public class ZjWorkSuspendServiceImpl extends ServiceImpl<ZjWorkSuspendMapper, ZjWorkSuspend> implements ZjWorkSuspendService {
    @Resource
    private ZjWorkSuspendMapper workSuspendMapper;
    @Resource
    private ZjWorkSuspendAnnexService workSuspendAnnexService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjWorkDetailService workDetailService;
    @Resource
    private ZjWorkChangeEngineerService workChangeEngineerService;
    @Resource
    private ZjNetworkEmpRelationService networkEmpRelationService;
    @Resource
    private ZjWorkModuleService workModuleService;

    // 根据工单ID获取工单挂起设置
    @Override
    public Map<String, Object> getOrderSuspendConfig(Long workId) {
        QueryWrapper<ZjWorkOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.select("id", "module_id")
                .eq("id", workId);
        ZjWorkOrder order = workOrderService.getOne(orderQueryWrapper);
        Assert.notNull(order, "工单数据不存在：" + workId);
        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("id", "is_enable_suspend AS enableSuspend")
                .eq("id", order.getModuleId());
        ZjWorkModule module = workModuleService.getOne(moduleQueryWrapper);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("enableSuspend", module.getEnableSuspend());
        return resultMap;
    }

    // 服务工程师申请工单挂起
    @Override
    @Transactional
    public void networkEmpApplySuspend(AccounLoginInfo loginInfo, Long workId, NetworkMobileWorkSuspendVo workSuspendVo) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "申请挂起的工单参数[ " + workId + " ]的数据不存在");
        // 是否有申请挂起的
        Assert.isTrue(order.getSuspendStatus() == 0, order.getSuspendStatus() == 1? "当前工单已申请挂起待审核，禁止重复操作" : "当前工单已挂起，禁止重复操作");
        Assert.isTrue(order.getStatus() == WorkConstant.WORK_STATUS_3,
                order.getStatus() == WorkConstant.WORK_STATUS_1 ? "当前工单未派单，禁止操作挂起申请" :
                        order.getStatus() == WorkConstant.WORK_STATUS_2 ? "当前工单待服务商确认接单中，禁止操作挂起申请" :
                                order.getStatus() == WorkConstant.WORK_STATUS_4 ? "当前工单已完成，禁止操作挂起申请" : "当前工单已取消，禁止操作挂起申请"
        );
        // 是否当前操作人的工单
        Assert.isTrue(Objects.equals(order.getNetworkEmpId(), loginInfo.getNetworkEmpId()), "当前工单不是您的服务工单，禁止操作挂起申请");

        ZjNetworkEmpRelation empRelation = networkEmpRelationService.getNetworkEmpIdAndNetworkId(loginInfo.getNetworkEmpId(), loginInfo.getNetworkId());
        // 判断是否为工程师
        boolean manager = null != empRelation && (empRelation.getManager() || empRelation.getSuperManager());
        if (!manager) {
            // 校验工单是否转单或转单待审核
            boolean hasWaitOrder = workChangeEngineerService.isApplyChangeEngineerWaitCheck(workId);
            Assert.isFalse(hasWaitOrder, "当前工单已申请转单待审核中，禁止操作");
        }
        // 查询是否有待审核的挂起工单
        Assert.isTrue(null == workSuspendMapper.isWaitCheckSuspendOrder(workId),"当前工单已申请挂起，待审核中，禁止重复申请");

        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("id", "is_enable_suspend AS enableSuspend", "is_auto_check_suspend AS autoCheckSuspend")
                .eq("id", order.getModuleId());
        ZjWorkModule module = workModuleService.getOne(moduleQueryWrapper);
        Assert.isTrue(module.getEnableSuspend(), "当前工单已关闭挂起功能，不允许申请工单挂起");

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(workId);
        updateOrder.setWaitCopeEvent(order.getWaitCopeEvent() +1);
        updateOrder.setSuspendStatus(module.getAutoCheckSuspend()? 2 : 1);
        updateOrder.setSuspendTime(new Date());
        workOrderService.updateById(updateOrder);

        ZjWorkSuspend suspend = new ZjWorkSuspend();
        suspend.setId(IdWorker.getId());
        suspend.setCustAccId(loginInfo.getCustAccId());
        suspend.setWorkId(workId);
        suspend.setStatus(module.getAutoCheckSuspend()? WorkConstant.WORK_SUSPEND_STATUS_2 : WorkConstant.WORK_SUSPEND_STATUS_1);
        suspend.setApplyEmpType(WorkConstant.WORK_SUSPEND_APPLY_EMP_TYPE_3);
        suspend.setApplyEmpId(loginInfo.getNetworkEmpId());
        suspend.setApplyEmp(loginInfo.getName());
        suspend.setRemark(workSuspendVo.getRemark());
        suspend.setCheckEmpType(0);
        suspend.setCheckEmpId(0L);
        suspend.setCheckEmp(module.getAutoCheckSuspend()? "系统" : "");
        suspend.setCheckRemark("");
        this.save(suspend);
        workSuspendAnnexService.save(loginInfo.getCustAccId(), suspend.getId(), workSuspendVo.getPaths());
        WorkServiceLog.saveNetwork(new WorkLogVo(loginInfo, workId, "工程师申请挂起工单", workSuspendVo.getRemark(), workSuspendVo.getPaths()));
        if (module.getAutoCheckSuspend()) {
            WorkServiceLog.saveNetwork(new WorkLogVo(loginInfo.getCustAccId(), "系统", workId, "工单挂起自动审核通过"));
        }
    }

    // 服务工程师取消工单挂起
    @Override
    public void networkEmpRestartSuspendOrder(AccounLoginInfo loginInfo, Long workId) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "取消挂起的工单参数[ " + workId + " ]的数据不存在");
        // 是否有申请挂起的
        Assert.isTrue(order.getSuspendStatus() == 1 || order.getSuspendStatus() == 2, "当前没有挂起的工单，无法执行取消或重启工单操作");
        // 是否当前操作人的工单
        Assert.isTrue(Objects.equals(order.getNetworkEmpId(), loginInfo.getNetworkEmpId()), "当前工单不是您的服务工单，禁止取消挂起或重启工单操作");
        QueryWrapper<ZjWorkSuspend> wrapper = new QueryWrapper<>();
        wrapper.select("id")
                .eq("work_id", workId)
                .eq("status", WorkConstant.WORK_SUSPEND_STATUS_2);
        ZjWorkSuspend suspend = this.getOne(wrapper);
        Assert.notNull(suspend, "当前工单没有挂起，无需取消挂起或重启工单操作");

        suspend.setStatus(WorkConstant.WORK_SUSPEND_STATUS_0);
        suspend.setRestart(new Date());
        this.updateById(suspend);

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setNewAdvance(order.getNewAdvance() +1);
        updateOrder.setSuspendStatus(0);
        updateOrder.setSuspendTime(null);
        workOrderService.update(updateOrder, new QueryWrapper<ZjWorkOrder>().eq("id", workId));
        WorkServiceLog.saveNetwork(new WorkLogVo(loginInfo, workId, "服务商工程师取消挂起工单"));
    }

    // 获取待审核的挂起工单
    @Override
    public WorkSuspendDetailVo getWaitCheckSupendOrder(Long workId) {
        ZjWorkSuspend suspend = getWaitCheckFeeByWorkId(workId);
        Assert.notNull(suspend, "当前工单没有待审核的挂起工单");

        WorkSuspendDetailVo vo = new WorkSuspendDetailVo();
        vo.setId(suspend.getId());
        vo.setRemark(suspend.getRemark());
        vo.setApplyEmpType(suspend.getApplyEmpType());
        vo.setApplyEmp(suspend.getApplyEmp());
        vo.setPaths(workSuspendAnnexService.getByWorkSuspendId(suspend.getId()).stream().map(ZjWorkSuspendAnnex::getPath).toList());
        return vo;
    }

    // 根据工单ID获取挂起待审核的工单
    @Override
    public ZjWorkSuspend getWaitCheckFeeByWorkId(Long workId) {
        QueryWrapper<ZjWorkSuspend> wrapper = new QueryWrapper<>();
        wrapper.select("id", "status", "apply_emp_type", "apply_emp_id", "remark", "gmt_create")
                .eq("status", WorkConstant.WORK_SUSPEND_STATUS_1)
                .eq("work_id", workId);
        return this.getOne(wrapper);
    }

    // 审核挂起的工单
    @Override
    @Transactional
    public void checkSuspendOrder(AccounLoginInfo loginInfo, Long workId, WorkSuspendChecklVo suspendChecklVo) {
        ZjWorkOrder order = workOrderService.getById(workId);
        Assert.notNull(order, "挂起的工单参数[ " + workId + " ]的数据不存在");

        ZjWorkSuspend suspend = this.getById(suspendChecklVo.getId());
        Assert.notNull(suspend, "没有待审核挂起的工单");
        Assert.isTrue(suspend.getStatus() == WorkConstant.WORK_SUSPEND_STATUS_1, "没有待审核挂起的工单");
        // 判断是否有客服
        if (order.getEmpId() > 0) {
            Assert.isTrue(Objects.equals(order.getEmpId(), loginInfo.getId()), "您不是当前工单的客服，无法审核挂起的工单");
        } else {
            ZjWorkDetail workDetail = workDetailService.getById(workId);
            Assert.isTrue(Objects.equals(workDetail.getDispatchEmpId(), loginInfo.getId()), "您不是当前工单的派工人员，无法审核挂起的工单");
        }
        ZjWorkSuspend updateSuspend = new ZjWorkSuspend();
        updateSuspend.setId(suspend.getId());
        updateSuspend.setStatus(suspendChecklVo.getType());
        updateSuspend.setCheckEmpType(WorkConstant.WORK_SUSPEND_CHECK_EMP_TYPE_1);
        updateSuspend.setCheckEmpId(loginInfo.getId());
        updateSuspend.setCheckTime(new Date());
        updateSuspend.setCheckRemark(suspendChecklVo.getRemark());
        this.updateById(updateSuspend);

        ZjWorkOrder updateOrder = new ZjWorkOrder();
        updateOrder.setId(IdWorker.getId());
        updateOrder.setWaitCopeEvent(order.getWaitCopeEvent() -1);
        if (suspendChecklVo.getType() == 2) {
            updateOrder.setSuspendStatus(2);
            updateOrder.setSuspendTime(new Date());
        } else {
            updateOrder.setSuspendStatus(0);
        }
        workOrderService.updateById(updateOrder);
        WorkServiceLog.saveService(new WorkLogVo(loginInfo, workId, "审核挂起的工单", suspend.getCheckRemark()));
    }
}
